package com.zhijian.medical.service.impl;

import cn.hutool.core.date.DateUtil;
import com.zhijian.medical.dao.local.ProductSendOutDetailMapper;
import com.zhijian.medical.entity.po.Agentia;
import com.zhijian.medical.entity.po.Product;
import com.zhijian.medical.entity.po.ProductSendOutDetail;
import com.zhijian.medical.entity.po.ProductSendOutDetailBatch;
import com.zhijian.medical.entity.vo.request.ProductSendOutDetailBatchSearchVo;
import com.zhijian.medical.entity.vo.request.ProductSendOutDetailSearchVo;
import com.zhijian.medical.entity.vo.response.ProductSendOutDetailBatchVo;
import com.zhijian.medical.entity.vo.response.ProductSendOutDetailVo;
import com.zhijian.medical.enums.ProductSendOutDetailStatusEnum;
import com.zhijian.medical.enums.ProductTurnStatusEnum;
import com.zhijian.medical.enums.ResponseCodeEnum;
import com.zhijian.medical.exception.BusinessException;
import com.zhijian.medical.service.*;
import com.zhijian.medical.util.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 产品发货填写表单业务处理层
 *
 * @author HCG
 * @version: 1.0
 * @date 2022-03-19 22:54:07
 */
@Slf4j
@Service
public class ProductSendOutDetailServiceImpl implements ProductSendOutDetailService {

    @Autowired
    private ProductSendOutDetailMapper mapper;

    @Autowired
    private ProductService productService;

    @Autowired
    private AgentiaService agentiaService;

    @Autowired
    private PersonGroupService personGroupService;

    @Autowired
    private ProductSendOutDetailBatchService productSendOutDetailBatchService;

    @Override
    public ProductSendOutDetail selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public ProductSendOutDetailVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public ProductSendOutDetailVo selectVoByCode(String code) {
        return mapper.selectVoByCode(code);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public Long insert(ProductSendOutDetail productSendOutDetail) {
        Date now = new Date();
        productSendOutDetail.setCreateTime(now);
        productSendOutDetail.setUpdateTime(now);
        return mapper.insert(productSendOutDetail) > 0 ? productSendOutDetail.getId() : 0L;
    }

    @Override
    public boolean update(ProductSendOutDetail productSendOutDetail) {
        Date now = new Date();
        productSendOutDetail.setUpdateTime(now);
        return mapper.updateByPrimaryKey(productSendOutDetail) != 0;
    }

    @Override
    public Integer count(ProductSendOutDetailSearchVo productSendOutDetailSearchVo) {
        return mapper.count(productSendOutDetailSearchVo);
    }

    @Override
    public List<ProductSendOutDetailVo> selectList(ProductSendOutDetailSearchVo productSendOutDetailSearchVo) {
        return mapper.selectList(productSendOutDetailSearchVo);
    }

    @Override
    public Page<ProductSendOutDetailVo> selectPage(ProductSendOutDetailSearchVo productSendOutDetailSearchVo) {
        //先直接查总数
        int count = count(productSendOutDetailSearchVo);
        //分页
        Page<ProductSendOutDetailVo> page = new Page<>(true, count, productSendOutDetailSearchVo.getPageNum(), productSendOutDetailSearchVo.getPageSize());
        productSendOutDetailSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<ProductSendOutDetailVo> responseVos = this.selectList(productSendOutDetailSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public boolean harvest(Long personId, Long id) {
        ProductSendOutDetail productSendOutDetail = this.selectById(id);
        if (Objects.isNull(productSendOutDetail)) {
            throw new BusinessException(ResponseCodeEnum.FAILURE.code, "此发货记录不存在或者已被删除");
        }
        if (productSendOutDetail.getStatus().intValue() == ProductSendOutDetailStatusEnum.ALREADY_HARVEST.getCode().byteValue()) {
            throw new BusinessException(ResponseCodeEnum.FAILURE.code, "此发货记录已确认收获，请勿重复操作");
        }
        Product product = productService.selectById(productSendOutDetail.getProductId());
        if (Objects.isNull(product)) {
            throw new BusinessException(ResponseCodeEnum.FAILURE.code, "此发货记录对应的产品订单不存在或者已被删除");
        }
        if (Objects.nonNull(personId) && !Objects.equals(product.getApplyUserId(), personId)) {
            throw new BusinessException(ResponseCodeEnum.FAILURE.code, "您没有权限进行确认收货，必须由申请人确认收货");
        }
        Date now = new Date();
        mapper.updateByPrimaryKeySelective(ProductSendOutDetail.builder()
                .id(id)
                .status(ProductSendOutDetailStatusEnum.ALREADY_HARVEST.getCode().byteValue())
                .updateTime(now)
                .build());
        //查询申请人的组
        List<Long> groupIds = personGroupService.selectGroupIdsByPersonId(Objects.nonNull(product.getApplyUserId()) ? product.getApplyUserId() : 0);
        List<ProductSendOutDetailBatchVo> productSendOutDetailBatchVos = productSendOutDetailBatchService.selectList(ProductSendOutDetailBatchSearchVo.builder()
                .detailId(id)
                .build());
        productSendOutDetailBatchVos.forEach(productSendOutDetailBatchVo -> {
            //修改发货批次的结束时间，这里主要用来查询轨迹
            productSendOutDetailBatchService.updateByPrimaryKeySelective(ProductSendOutDetailBatch.builder()
                    .id(productSendOutDetailBatchVo.getId())
                    .endTime(now)
                    .build());
            //入库试剂，新增一条记录
            agentiaService.insert(Agentia.builder()
                    .name(product.getName())
                    .number(product.getNumber())
                    .batchNumber(productSendOutDetailBatchVo.getBatchNumber())
                    .stock(productSendOutDetailBatchVo.getQuantity())
                    .brand(product.getBrand())
                    .categoryId(product.getAgentiaCategoryId())
                    .groupId(!CollectionUtils.isEmpty(groupIds) ? groupIds.get(0) : null)
                    .storageDate(DateUtil.formatDate(now))
                    .build()
            );

        });
        //查询已经确认收货的数量
        int sumQuantity = this.sumQuantity(ProductSendOutDetailSearchVo.builder()
                .productId(product.getId())
                .status(ProductSendOutDetailStatusEnum.ALREADY_HARVEST.getCode().byteValue())
                .build());
        //如果确认收货的数量大于等于申请的数量，就把订单状态改为已完成
        if (sumQuantity >= product.getQuantity()) {
            productService.updateByPrimaryKeySelective(Product.builder()
                    .id(product.getId())
                    .status(ProductTurnStatusEnum.HARVEST.getCode().byteValue())
                    .updateTime(now)
                    .build());
        }
        return true;
    }

    @Override
    public int sumQuantity(ProductSendOutDetailSearchVo productSendOutDetailSearchVo) {
        return mapper.sumQuantity(productSendOutDetailSearchVo);
    }

}